package tr.gov.tubitak.bilgem.esya.certviewer.viwerasn;

import sun.security.util.DerInputStream;
import sun.security.util.DerValue;
import sun.security.util.ObjectIdentifier;
import sun.security.x509.CertAttrSet;
import sun.security.x509.Extension;
import sun.security.x509.OIDMap;
import tr.gov.tubitak.bilgem.esya.certviewer.Bundle;

import java.io.IOException;
import java.io.OutputStream;
import java.security.cert.CertificateException;
import java.util.Enumeration;

/**
 * Created by IntelliJ IDEA.
 * User: ramazan.girgin
 * Date: 08.12.2011
 * Time: 09:08
 * To change this template use File | Settings | File Templates.
 */
public class QCStatementExtension extends Extension implements CertAttrSet{
    ObjectIdentifier etsiNesStatementObjId=null;
    String etsiNesStatementStr="";

    ObjectIdentifier tkNesStatementObjId=null;
    String tkNesStatementStr="";

    ObjectIdentifier moneyLimitId=null;
    String currency;
    int amount;
    int exponent;

    ObjectIdentifier complianceObjectIdentifier;
    ObjectIdentifier moneyObjectIdentifier;

    ObjectIdentifier nesStatementObjId;
    String nesStatementStr;

    final static String ETSI_NES_ID = "0.4.0.1862.1.1";
    final static String TK_NES_ID="2.16.792.1.61.0.1.5070.1.1";
    final static String MONEY_LIMIT_ID="0.4.0.1862.1.2";

    public static String getExtensionIdStr() {
        return "1.3.6.1.5.5.7.1.3";
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        if(etsiNesStatementObjId!=null)
        {
           stringBuilder.append(Bundle.getString("QCStatementExtension.ETSICompliance")+"\n");
            stringBuilder.append("\t"+etsiNesStatementStr+"\n");
        }

        if(tkNesStatementObjId != null)
        {
           stringBuilder.append(Bundle.getString("QCStatementExtension.TKCompliance")+":\n");
           stringBuilder.append("\t"+tkNesStatementStr+"\n");
        }

        if(moneyLimitId!=null)
        {
             stringBuilder.append(Bundle.getString("QCStatementExtension.MoneyLimit")+":\n");
             int exponentValue = (int) Math.pow(10,exponent);
             int moneyLimitAmount = amount*exponentValue;
             stringBuilder.append("\t"+moneyLimitAmount+" "+currency);
        }

        return stringBuilder.toString();
    }

    public QCStatementExtension(Boolean critical, Object value)
            throws IOException {
        this.extensionId = new ObjectIdentifier("1.3.6.1.5.5.7.1.3");
        this.critical = critical.booleanValue();

        if (!(value instanceof byte[])) {
            throw new IOException("Illegal argument type");
        }
        extensionValue = (byte[])value;

        ////////////////////
        DerValue val = new DerValue(this.extensionValue);
        if (val.tag != DerValue.tag_Sequence) {
            throw new IOException("Sequence tag missing for QCStatement.");
        }

        DerInputStream in = val.data;
        while (in != null && in.available() != 0) {
            DerValue next = in.getDerValue();
            byte elementTag = next.tag;
            if (val.tag != DerValue.tag_Sequence) {
                throw new IOException("Sequence tag missing for QCStatement.");
            }

            DerInputStream elementIn = next.data;
            ObjectIdentifier lastObjId=null;
            while (elementIn != null && elementIn.available() != 0) {
                DerValue nextElementValue = elementIn.getDerValue();
                byte nextElementTag = nextElementValue.tag;
                if(nextElementTag == DerValue.tag_ObjectId){
                    try{
                        lastObjId=null;
                        String asString = nextElementValue.getAsString();
                        //byte[] bitString = nextElementValue.getBitString();
                        ObjectIdentifier elementOID = nextElementValue.getOID();
                        if(elementOID.equals(new ObjectIdentifier(ETSI_NES_ID)))
                        {
                            etsiNesStatementObjId=elementOID;
                            lastObjId = etsiNesStatementObjId;
                        }else if(elementOID.equals(new ObjectIdentifier(TK_NES_ID)))
                        {
                            tkNesStatementObjId=elementOID;
                            lastObjId = tkNesStatementObjId;
                        }
                        else if(elementOID.equals(new ObjectIdentifier(MONEY_LIMIT_ID)))
                        {
                            moneyLimitId=elementOID;
                            lastObjId = moneyLimitId;
                        }
                    }catch (Exception exc){
                        exc.printStackTrace();
                    }
                    continue;
                }
                if(lastObjId == moneyLimitId){
                    if(nextElementValue.tag != DerValue.tag_Sequence)
                    {
                        continue;
                    }
                    int index=0;
                    DerInputStream moneyElementIn = nextElementValue.data;
                    while (moneyElementIn != null && moneyElementIn.available() != 0) {
                        DerValue moneyElementSubValue = moneyElementIn.getDerValue();
                        if(index == 0){
                            currency = moneyElementSubValue.getPrintableString();
                        }
                        else if(index == 1){
                            amount = moneyElementSubValue.getInteger();
                        }
                        else if(index == 2){
                            exponent = moneyElementSubValue.getInteger();
                        }
                        index++;
                    }
                }
                else if(nextElementTag == DerValue.tag_UTF8String){
                    if(lastObjId == etsiNesStatementObjId){
                        etsiNesStatementStr=nextElementValue.getUTF8String();
                    }
                    else if(lastObjId == tkNesStatementObjId){
                        tkNesStatementStr=nextElementValue.getUTF8String();
                    }
                }
            }
        }
    }
    ///////////////////
    /*

    DerValue osv = new DerValue(extensionValue);
    if(osv.tag==DerValue.tag_SequenceOf)
    {
        //QC Compliance
        try{
            DerInputStream data = osv.getData();
            while (data.available()>0)
            {
                DerValue derValue = data.getDerValue();
                byte tag = derValue.getTag();
                if(tag==DerValue.tag_SequenceOf){
                    DerInputStream sequenceData = derValue.getData();
                    byte sequenceTag = sequenceData.tag;
                    if(sequenceTag == DerValue.tag_ObjectId){
                        ObjectIdentifier seqOID = derValue.getOID();
                        int b=7;
                    }
                }
                if(tag == DerValue.tag_ObjectId){
                    ObjectIdentifier oid = derValue.getOID();
                    int b=7;
                }
                int a=5;
            }
            DerValue[] qccompliance = osv.data.getSequence(0);
            DerValue complianceFirstDerValue = qccompliance[0];
            if(complianceFirstDerValue.tag == DerValue.tag_ObjectId)
            {
                //complianceObjectIdentifier = complianceFirstDerValue.getOID();
            }

            DerValue qcStatementSecond = qccompliance[1];
            if(qcStatementSecond.tag==DerValue.tag_UTF8String)
            {
                String str  = qcStatementSecond.getUTF8String();
                int a=5;
            }
        }
        catch(Exception e){
            e.printStackTrace();
        }

        try{
            //Money
            DerValue[] money = osv.data.getSequence(1);
            DerValue moneyFirstDerValue = money[0];
            if(moneyFirstDerValue.tag == DerValue.tag_ObjectId)
            {
                moneyObjectIdentifier =moneyFirstDerValue.getOID();
            }
            if(money.length>1)
            {
                DerValue moneySecondDerValue = money[1];
                if(moneySecondDerValue.tag == DerValue.tag_Sequence)
                {
                    DerInputStream ins = moneySecondDerValue.getData();
                    currency = ins.getPrintableString();
                    amount = ins.getInteger();
                    exponent = ins.getInteger();
                }
            }
        }
        catch(Exception e){
            e.printStackTrace();
        }

        //TK nitelikli ibaresi
        try
        {
            DerValue[] qcStatementStrDerValue = osv.data.getSequence(2);
            DerValue qcStatementFirst = qcStatementStrDerValue[0];
            if(qcStatementFirst.tag == DerValue.tag_ObjectId)
            {
                nesStatementObjId = qcStatementFirst.getOID();
            }

            DerValue qcStatementSecond = qcStatementStrDerValue[1];
            if(qcStatementSecond.tag==DerValue.tag_UTF8String)
            {
                nesStatementStr = qcStatementSecond.getUTF8String();
            }
        }
        catch (Exception exc){
            exc.printStackTrace();
        }
    }
}       */

    @Override
    public void encode(OutputStream out) throws CertificateException, IOException {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void set(String name, Object obj) throws CertificateException, IOException {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Object get(String name) throws CertificateException, IOException {
        return Bundle.getString("QCStatementExtension.name");
    }

    @Override
    public void delete(String name) throws CertificateException, IOException {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Enumeration getElements() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public String getName() {
        return Bundle.getString("QCStatementExtension.name");
    }

    @Override
    public ObjectIdentifier getExtensionId() {
        try {
            return  new ObjectIdentifier(QCStatementExtension.getExtensionIdStr());
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return super.getExtensionId();    //To change body of overridden methods use File | Settings | File Templates.
    }
}
